#pragma once

#include <iostream>
#include <vector>
#include <functional>
#include <fcntl.h>

using func_t = std::function<void ()>;


/**
 * (套接字)的模式设置成非阻塞状态
 * 虽然还有其他设置非阻塞的方法，但这一种是最通用的
 * 因为其他的几乎只能设置读或写为非阻塞，而这种方式能将读和写都设置成非阻塞
 * 
 * @param fd: int 需要设置为非阻塞状态的文件描述符(套接字)
*/
void setNonBlock(const int& fd) {
    // 当fcntl的第二个参数为F_GETFL时，可以不写后面的可变参数列表
    int flag = fcntl(fd, F_GETFL); // 获取fd原本的模式如O_RDONLY, O_WRONLY

    if (flag < 0) {
        std::perror("fcntl");
        return;
    }

    fcntl(fd, F_SETFL, flag | O_NONBLOCK); // 将fd设置为非阻塞模式
}

void logTask() {
    std::cout << "This is a log" << std::endl;
}

void downloadTask() {
    std::cout << "downloading ..." << std::endl;
}

void uploadTask() {
    std::cout << "uploading ..." << std::endl;
}

/**
 * 初始化任务数组，将任务加载进去
*/
inline void initTasks(std::vector<func_t>& call_backs) {
    call_backs.push_back(logTask);
    call_backs.push_back(downloadTask);
    call_backs.push_back(uploadTask);
}

/**
 * 执行一轮任务
*/
inline void execTasks(const std::vector<func_t>& call_backs) {
    for (const auto &task : call_backs) {
        task();
    }
}